<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of Airmail
 *
 * @author ketu
 */
class Zhishidi_Express_Model_Express extends Mage_Core_Model_Abstract {
    const XML_ZHISHIDI_EXPRESS_SETTINGS_PATH = 'carriers/zhishidi_express/';


    protected $tableRateWeightUnit = array();

    protected function _construct() {
        $this->_init('zhishidi_express/express');
    }

    public function getExpress($weight, $country, $state = "") {
        $typeCollection = Mage::getModel('zhishidi_express/type')->getCollection()->addVisibleFilter();

        $carrier = array();
        $zone = null;
        $netWeight = $weight;

        if (Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'boxes_weight') > 0) {
            $weight += $weight * Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'boxes_weight');
        }
        $packageWeight = $weight;
        foreach ($typeCollection as $type) {
            $weight = $this->calculateWeight($type, $packageWeight);

            $zone = $this->getZoneUnit($type, $weight, $country, $state);

            if (!$zone) {
                continue;
            }
            $shippingCost = $this->getShippingCost($type, $zone, $weight);
            //echo '<br>';
            if ($type->getTypeDiscount() && $type->getTypeDiscount() > 0) {
                $shippingCost = $shippingCost * $type->getTypeDiscount();
            }
            if ($type->getTypeSurcharge() && $type->getTypeSurcharge() > 0) {
                $shippingCost += $shippingCost * $type->getTypeSurcharge();
            }

            if (Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'enable_handle') && Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'handle') > 0) {
                $shippingCost -= Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'handle') * $netWeight;
            }

            if (Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'currency') && Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'currency') > 0) {
                $shippingCost = $shippingCost / Mage::getStoreConfig(self::XML_ZHISHIDI_EXPRESS_SETTINGS_PATH . 'currency');
            }

            $carrier[$type->getTypeCode()] = array(
                'cost' => $shippingCost,
                'method' => $type->getTypeCode(),
                'title' => $type->getTypeName(),
            );
        }
        return $carrier;
    }

    protected function calculateWeight($type, $weight) {
        if ($weight < $type->getTypeWeightUnit())
            $weight = $type->getTypeWeightUnit();

        $weightUnit = $type->getTypeWeightUnit();
        if ($type->getTypeSepWeight() && $weight >= $type->getTypeSepWeight() && $type->getTypeSepWeightUnit()) {
            $weightUnit = $type->getTypeSepWeightUnit();
            $this->tableRateWeightUnit[$type->getTypeCode()] = $type->getTypeSepWeightUnit();
        }
        $maxWeightCount = ceil($weight / $weightUnit);
        return ($maxWeightCount * $weightUnit);
    }

    protected function getTableRate($type, $zone, $weight) {
        if ($type->getTypeSepWeight() && $weight < $type->getTypeSepWeight() && $type->getTypeHandle() == 'fixed_table_rate') {
            return $zone->getZonePrice() + (intval($weight / $type->getTypeWeightUnit()) - 1) * $zone->getZoneUnit();
        }

        $weightUnit = isset($this->tableRateWeightUnit[$type->getTypeCode()]) ? $this->tableRateWeightUnit[$type->getTypeCode()] : $type->getTypeWeightUnit();

        $queryWeight = $weight - ($weightUnit / 2);
        $rateCollection = Mage::getModel('zhishidi_express/rate')->getCollection()
                        ->addZoneToFilter($zone->getMapZone())
                        ->setWeightRange($queryWeight)
                        ->setPageSize(1);
        //echo $rateCollection->getSelect()->__toString();
        //echo '<br />';
        $rate = $rateCollection->getFirstItem();
        if ($rate) {
            return $rate->getRatePrice();
        }
        return false;
    }

    protected function getShippingCost($type, $zone, $weight) {
        $shippingCost = 0;
        if ($type->getTypeMaxWeight() && $weight > $type->getTypeMaxWeight()) {
            $_max = floor($weight / $type->getTypeMaxWeight());
            $weight = fmod($weight, $type->getTypeMaxWeight());
            if ($type->getTypeHandle() == 'fixed')
                $shippingCost += $_max * ($zone->getZonePrice() + (intval($type->getTypeMaxWeight() / $type->getTypeWeightUnit()) - 1) * $zone->getZoneUnit());
            else
                $shippingCost += $_max * ($this->getTableRate($type, $zone, $type->getTypeMaxWeight()));
        }

        if ($type->getTypeHandle() == 'fixed')
            $shippingCost += ( $zone->getZonePrice() + (intval($weight / $type->getTypeWeightUnit()) - 1) * $zone->getZoneUnit());
        else
            $shippingCost += $this->getTableRate($type, $zone, $weight);
        return $shippingCost;
    }

    protected function getZoneUnit($type, $weight, $country, $state = null) {
        $_zoneCollection = Mage::getModel('zhishidi_express/map')->getCollection()
                        ->joinZone()
                        ->joinZoneConfig()
                        ->addCountryFilter($country)
                        ->addVisibleFilter()
                        ->addTypeFilter($type->getId());
        if ($type->getTypeSepWeight() && $weight >= $type->getTypeSepWeight()) {
            $_zoneCollection->addFieldToFilter('zone_group', $type->getTypeSepGroup());
        } else {
            $_zoneCollection->addFieldToFilter('zone_group', 0);
        }
        //echo $_zoneCollection->getSelect()->__toString();
        //echo '<br>';
        $zoneUnit = null;
        if (count($_zoneCollection) > 0) {
            foreach ($_zoneCollection as $zone) {
                $zoneState = $zone->getState();
                if ($state && $zoneState && $state == $zoneState) {
                    $zoneUnit = $zone;
                    break;
                } elseif (empty($zoneState)) {
                    $zoneUnit = $zone;
                    break;
                }
            }
            return $zoneUnit;
        }
        return false;
    }

}